﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Kugar.Core.ExtMethod
{
        public static class DataGridViewExt
        {
            /// <summary>
            ///     设置指定行的背景色
            /// </summary>
            /// <param name="dg"></param>
            /// <param name="rowindex">指定的行号</param>
            /// <param name="color">要设置的背景色</param>
            public static void SetRowBackColor(this DataGridView dg, int rowindex, Color color)
            {
                if (dg == null || dg.Rows.Count <= 0 || rowindex > dg.Rows.Count - 1)
                {
                    return;
                }

                var row = dg.Rows[rowindex];
                if (row == null)
                {
                    return;
                }

                row.SetBackColor(color);
            }

            /// <summary>
            ///     获取指定行号，指定列名的单元格的背景色
            /// </summary>
            /// <param name="dg"></param>
            /// <param name="rowindex">指定的行号</param>
            /// <param name="colindex">指定的列号</param>
            public static Color GetCellBackColor(this DataGridView dg, int rowindex, int colindex)
            {
                if (dg == null || dg.Rows.Count <= 0 || rowindex > dg.Rows.Count - 1 || colindex <= 0 || colindex > dg.Columns.Count - 1)
                {
                    return Color.Empty;
                }

                var color = dg.Rows[rowindex].Cells[colindex].Style.BackColor;
                return color;
            }

            /// <summary>
            ///     获取指定行号，指定列名的单元格的背景色
            /// </summary>
            /// <param name="dg"></param>
            /// <param name="rowindex">指定的行号</param>
            /// <param name="colname">指定的列名</param>
            public static Color GetCellBackColor(this DataGridView dg, int rowindex, string colname)
            {
                if (dg == null || dg.Rows.Count <= 0 || rowindex > dg.Rows.Count - 1 || string.IsNullOrEmpty(colname) || !dg.Columns.Contains(colname))
                {
                    return Color.Empty;
                }

                var color = dg.Rows[rowindex].Cells[colname].Style.BackColor;
                return color;
            }

            /// <summary>
            ///     设置指定行号，指定列名的单元格的背景色
            /// </summary>
            /// <param name="dg"></param>
            /// <param name="rowindex">指定的行号</param>
            /// <param name="colindex">指定的列号</param>
            /// <param name="color">设置的背景色</param>
            public static void SetCellBackColor(this DataGridView dg, int rowindex, int colindex, Color color)
            {
                if (dg == null || dg.Rows.Count <= 0 || rowindex > dg.Rows.Count - 1 || colindex <= 0 || colindex > dg.Columns.Count - 1)
                {
                    return;
                }

                try
                {
                    dg.Rows[rowindex].Cells[colindex].Style.BackColor = color;
                }
                catch (Exception)
                {
                }

            }

            /// <summary>
            ///     设置指定行号，指定列名的单元格的背景色
            /// </summary>
            /// <param name="dg"></param>
            /// <param name="rowindex">指定的行号</param>
            /// <param name="colname">指定的列名</param>
            /// <param name="color">设置的背景色</param>
            public static void SetCellBackColor(this DataGridView dg, int rowindex, string colname, Color color)
            {
                if (dg == null || dg.Rows.Count <= 0 || rowindex > dg.Rows.Count - 1 || string.IsNullOrEmpty(colname) || !dg.Columns.Contains(colname))
                {
                    return;
                }

                try
                {
                    dg.Rows[rowindex].Cells[colname].Style.BackColor = color;
                }
                catch (Exception)
                {
                }
            }

            /// <summary>
            ///     设置指定行号，指定列名的单元格的值
            /// </summary>
            /// <param name="dg"></param>
            /// <param name="rowindex">指定的行号</param>
            /// <param name="colindex">指定的列号</param>
            /// <param name="value"></param>
            public static void SetCellValue(this DataGridView dg, int rowindex, int colindex, object value)
            {
                if (dg == null || dg.Rows.Count <= 0 || rowindex > dg.Rows.Count - 1 || colindex <= 0 || colindex > dg.Columns.Count - 1)
                {
                    return;
                }

                try
                {
                    dg.Rows[rowindex].Cells[colindex].Value = value;
                }
                catch (Exception)
                {
                }

            }

            /// <summary>
            ///     设置指定行号，指定列名的单元格的值
            /// </summary>
            /// <param name="dg"></param>
            /// <param name="rowindex">指定的行号</param>
            /// <param name="colname">指定的列名</param>
            /// <param name="value"></param>
            public static void SetCellValue(this DataGridView dg, int rowindex, string colname, object value)
            {
                if (dg == null || dg.Rows.Count <= 0 || rowindex > dg.Rows.Count - 1 || string.IsNullOrEmpty(colname) || !dg.Columns.Contains(colname))
                {
                    return;
                }

                SetCellValue(dg, rowindex, dg.Columns[colname].Index, value);
            }


            /// <summary>
            ///     读取指定行号，指定列号的单元格的值
            /// </summary>
            /// <param name="dg"></param>
            /// <param name="rowindex">指定的行号</param>
            /// <param name="colindex">指定的列号</param>
            /// <returns></returns>
            public static object GetCellValue(this DataGridView dg, int rowindex, int colindex)
            {
                if (dg == null || dg.Rows.Count < 0 || rowindex > dg.Rows.Count - 1 || colindex < 0 || colindex > dg.Columns.Count - 1)
                {
                    return null;
                }

                var v = dg.Rows[rowindex].Cells[colindex].Value;
                return v;
            }

            /// <summary>
            ///     读取指定行号，指定列号的单元格的值
            /// </summary>
            /// <param name="dg"></param>
            /// <param name="rowindex">指定的行号</param>
            /// <param name="colname">指定的列名</param>
            /// <returns></returns>
            public static object GetCellValue(this DataGridView dg, int rowindex, string colname)
            {
                if (dg == null || dg.Rows.Count <= 0 || rowindex > dg.Rows.Count - 1 || string.IsNullOrEmpty(colname) || !dg.Columns.Contains(colname))
                {
                    return Color.Empty;
                }

                var v = dg.Rows[rowindex].Cells[colname].Value;
                return v;
            }


            /// <summary>
            ///     为DataGridView添加序号列
            /// </summary>
            /// <param name="dg"></param>
            /// <param name="isEnable">是否添加，true为添加，false为取消</param>
            [Obsolete]
            public static void AddLineIndex(this DataGridView dg, bool isEnable)
            {
                if (dg == null)
                {
                    return;
                }

                dg.RowPostPaint -= dataGridView_RowPostPaint;

                if (isEnable)
                {
                    dg.RowPostPaint += dataGridView_RowPostPaint;
                }

            }

            public static void AddRowIndex(this DataGridView dg, bool isEnable)
            {
                if (dg == null)
                {
                    return;
                }

                dg.RowPostPaint -= dataGridView_RowPostPaint;

                if (isEnable)
                {
                    dg.RowPostPaint += dataGridView_RowPostPaint;
                }
            }

            private static void dataGridView_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
            {
                if (!(sender is DataGridView))
                {
                    return;
                }

                var dg = (sender as DataGridView);

                var rectangle = new Rectangle(e.RowBounds.Location.X,
                                              Convert.ToInt32(e.RowBounds.Location.Y +
                                                              (e.RowBounds.Height -
                                                               dg.RowHeadersDefaultCellStyle.Font.Size) / 2),
                                              dg.RowHeadersWidth - 4, e.RowBounds.Height);


                TextRenderer.DrawText(e.Graphics, (e.RowIndex + 1).ToString(), dg.RowHeadersDefaultCellStyle.Font,
                                      rectangle, dg.RowHeadersDefaultCellStyle.ForeColor, TextFormatFlags.Right);
            }

            /// <summary>
            ///     获取当前单元格所在的列的列名
            /// </summary>
            /// <param name="cell">当前单元格</param>
            /// <returns></returns>
            public static string GetCellColName(this DataGridViewCell cell)
            {
                if (cell == null)
                {
                    return "";
                }

                return cell.DataGridView.Columns[cell.ColumnIndex].Name;
            }

            /// <summary>
            ///     读取指定行号，指定列号的单元格
            /// </summary>
            /// <param name="dg"></param>
            /// <param name="rowindex">指定的行号</param>
            /// <param name="colindex">指定的列号</param>
            /// <returns></returns>
            public static DataGridViewCell GetCell(this DataGridView dg, int rowindex, int colindex)
            {
                if (dg.Rows.Count < 0 || dg.Columns.Count < 0 || rowindex < 0 || rowindex > dg.Rows.Count - 1 || colindex < 0 || colindex > dg.ColumnCount)
                {
                    return null;
                }

                var row = dg.Rows[rowindex];
                if (row == null)
                {
                    return null;
                }

                var cell = row.Cells[colindex];
                return cell;
            }

            /// <summary>
            ///     读取指定行号，指定列名的单元格
            /// </summary>
            /// <param name="dg"></param>
            /// <param name="rowindex">指定的行号</param>
            /// <param name="colname">指定的列名</param>
            /// <returns></returns>
            public static DataGridViewCell GetCell(this DataGridView dg, int rowindex, string colname)
            {
                if (dg.Rows.Count < 0 || dg.Columns.Count < 0 || rowindex < 0 || rowindex > dg.Rows.Count - 1 || !dg.Columns.Contains(colname))
                {
                    return null;
                }

                return GetCell(dg, rowindex, dg.Columns[colname].Index);
            }

            /// <summary>
            ///     读取指定ComboBox类型的单元格中，ComboBox控件的选中值
            /// </summary>
            /// <param name="cmb"></param>
            /// <returns></returns>
            public static object GetSelectValue(this DataGridViewComboBoxCell cmb)
            {
                if (cmb == null || cmb.Value == null)
                {
                    return null;
                }

                foreach (var item in cmb.Items)
                {
                    if (item.ToString() == cmb.Value.ToString())
                    {
                        return item;
                    }
                }


                return null;
            }

            public static object GetItems(this DataGridViewComboBoxCell cmb, object value)
            {
                if (cmb == null || cmb.Items.Count <= 0 || value == null)
                {
                    return null;
                }

                for (int i = 0; i < cmb.Items.Count; i++)
                {
                    var item = cmb.Items[i];

                    if (item.Equals(value))
                    {
                        return item;
                    }
                }


                return null;
            }

            /// <summary>
            ///     获取指定Y坐标所在的Row对象
            /// </summary>
            /// <param name="gd"></param>
            /// <param name="mouseLocation_Y">指定的Y坐标</param>
            /// <returns>如果指定坐标存在行，则返回Row对象，否则返回null</returns>
            public static int GetRowIndexAt(this DataGridView gd, int mouseLocation_Y)
            {
                if (gd.FirstDisplayedScrollingRowIndex < 0)
                {
                    return -1;
                }
                if (gd.ColumnHeadersVisible == true && mouseLocation_Y <= gd.ColumnHeadersHeight)
                {
                    return -1;
                }
                int index = gd.FirstDisplayedScrollingRowIndex;
                int displayedCount = gd.DisplayedRowCount(true);
                for (int k = 1; k <= displayedCount; )
                {
                    if (gd.Rows[index].Visible == true)
                    {
                        Rectangle rect = gd.GetRowDisplayRectangle(index, true);  // 取该区域的显示部分区域   
                        if (rect.Top <= mouseLocation_Y && mouseLocation_Y < rect.Bottom)
                        {
                            return index;
                        }
                        k++;
                    }
                    index++;
                }
                return -1;
            }


            /// <summary>
            ///     设置行背景色
            /// </summary>
            /// <param name="row">指定行对象</param>
            /// <param name="color">要设置的背景色</param>
            public static void SetBackColor(this DataGridViewRow row, Color color)
            {
                if (row == null || row.Cells.Count <= 0)
                {
                    return;
                }

                foreach (DataGridViewCell cell in row.Cells)
                {
                    cell.Style.BackColor = color;
                }
            }

            public static void SetCellBackColor(this DataGridViewRow row, int colIndex, Color color)
            {
                if (row == null || row.Cells.Count <= 0 || colIndex < 0 || colIndex > row.Cells.Count - 1)
                {
                    return;
                }

                row.Cells[colIndex].Style.BackColor = color;
            }

            public static void SetCellBackColor(this DataGridViewRow row, string colName, Color color)
            {
                if (row == null || row.Cells.Count <= 0 || string.IsNullOrEmpty(colName) || !row.DataGridView.Columns.Contains(colName))
                {
                    return;
                }

                row.Cells[colName].Style.BackColor = color;
            }

            public static Color GetCellBackColor(this DataGridViewRow row, int colIndex)
            {
                if (row == null || row.Cells.Count <= 0 || colIndex < 0 || colIndex > row.Cells.Count - 1)
                {
                    return Color.Empty;
                }

                return row.Cells[colIndex].Style.BackColor;
            }

            public static Color GetCellBackColor(this DataGridViewRow row, string colName)
            {
                if (row == null || row.Cells.Count <= 0 || string.IsNullOrEmpty(colName) || !row.DataGridView.Columns.Contains(colName))
                {
                    return Color.Empty;
                }

                return row.Cells[colName].Style.BackColor;
            }

            public static void SetCellForeColor(this DataGridViewRow row, int colIndex, Color color)
            {
                row.Cells[colIndex].Style.ForeColor = color;
            }

            public static void SetCellForeColor(this DataGridViewRow row, string colName, Color color)
            {
                row.Cells[colName].Style.ForeColor = color;
            }

            public static void SetCellFont(this DataGridViewRow row,int colIndex, Font font)
            {
                row.Cells[colIndex].Style.Font = font;
            }

            public static void SetCellFont(this DataGridViewRow row, string colName, Font font)
            {
                row.Cells[colName].Style.Font = font;
            }

            public static void SetRowForeColor(this DataGridViewRow row, Color color)
            {
                var cols = row.DataGridView.Columns.Count;

                for (int i = 0; i < cols; i++)
                {
                    row.Cells[i].Style.ForeColor = color;
                }
            }

            public static void SetRowFont(this DataGridViewRow row, Font font)
            {
                var cols = row.DataGridView.Columns.Count;

                for (int i = 0; i < cols; i++)
                {
                    row.Cells[i].Style.Font = font;
                }
            }

            /// <summary>
            ///     添加一个新行,并返回该行的引用
            /// </summary>
            /// <param name="collection"></param>
            /// <returns></returns>
            public static DataGridViewRow AddRow(this DataGridViewRowCollection collection)
            {
                var i = collection.Add();
                return collection[i];
            }

            /// <summary>
            ///     批量添加指定数量的新行,并返回该行的引用
            /// </summary>
            /// <param name="collection"></param>
            /// <param name="count">添加的数量</param>
            /// <returns></returns>
            public static DataGridViewRow[] AddRows(this DataGridViewRowCollection collection,int count)
            {
                if (count<0)
                {
                    throw new ArgumentOutOfRangeException(@"count");
                }

                var tempList = new DataGridViewRow[count];

                for (int j = 0; j < count; j++)
                {
                    tempList[j] = AddRow(collection);
                }

                return tempList;
            }

            /// <summary>
            ///     判断是否有选中行
            /// </summary>
            /// <param name="dg"></param>
            /// <returns></returns>
            public static bool HasSelectedRows(this DataGridView dg)
            {
                if (dg.SelectedRows.Count>0 || dg.SelectedCells.Count>0)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }

            /// <summary>
            ///     获取第一个选中的行对象
            /// </summary>
            /// <param name="dg"></param>
            /// <returns></returns>
            public static DataGridViewRow GetFirstSelectedRow(this DataGridView dg)
            {
                if (HasSelectedRows(dg))
                {
                    if (dg.SelectedRows.Count<=0)
                    {
                        return dg.Rows[dg.SelectedCells[0].RowIndex];
                    }
                    else
                    {
                        return dg.SelectedRows[0];
                    }
                }
                else
                {
                    return null;
                }
            }

            /// <summary>
            ///     获取所有选中的行对象
            /// </summary>
            /// <param name="dg"></param>
            /// <returns></returns>
            public static DataGridViewRow[] GetSelectedRows(this DataGridView dg)
            {
         
                var st = new HashSet<DataGridViewRow>();

                if (dg.SelectedRows.Count>0)
                {
                    foreach (DataGridViewRow selectedRow in dg.SelectedRows)
                    {
                        st.Add(selectedRow);
                    }
                }

                if (dg.SelectedCells.Count>0)
                {
                    foreach (DataGridViewCell dc in dg.SelectedCells)
                    {
                        var tempRow = dg.Rows[dc.RowIndex];
                        if (st.Contains(tempRow))
                        {
                            continue;
                        }
                        st.Add(tempRow);
                    }
                }

                if (st.Count<=0)
                {
                    return null;
                }

                return st.ToArray();
            }

    }
}
